package org.csu.vo;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

/**
 * 通用响应结果封装类（泛型设计，支持所有业务模块）
 * 作用：统一前后端交互的响应格式，解决不同接口返回结构不一致的问题，降低前后端对接成本
 * 核心价值：
 * 1. 前端无需适配多种返回格式，统一解析 success/code/message/data 字段
 * 2. 后端统一处理响应状态、提示信息，便于异常统一捕获和日志排查
 * 3. 泛型 T 支持任意业务数据类型（如 Book、List<Book>、PageInfo 等）
 */
public class BaseResponse<T> {
    /**
     * 操作结果标识：true=成功，false=失败
     * 前端可直接通过该字段判断业务是否执行成功（无需解析code）
     */
    private Boolean success;

    /**
     * 业务状态码（区别于HTTP状态码）
     * 用于前端精细化处理（如："SUCCESS"=成功，"ERROR"=通用失败，"ISBN_DUPLICATE"=ISBN重复等）
     * 建议通过常量类管理（如 SystemConstants），避免硬编码
     */
    private String code;

    /**
     * 响应提示信息：前端用于展示给用户（如"新增图书成功"、"ISBN格式错误"）
     */
    private String message;

    /**
     * 泛型业务数据：存储接口返回的核心业务数据
     * 示例：
     * - 新增图书接口：返回 Book 对象（包含新增后的图书完整信息）
     * - 图书列表接口：返回 List<Book> 或 PageInfo<Book>（分页数据）
     * - 简单操作接口（如下架）：返回 null 或 Boolean
     */
    private T data;

    /**
     * 响应时间戳：格式为 yyyy-MM-dd'T'HH:mm:ss（UTC+8时区）
     * 用于前端排查请求时序问题，或后端日志审计
     */
    private String timestamp;

    // ==================== 构造方法（私有，通过静态工厂方法创建对象，避免直接new）====================
    /**
     * 私有构造：强制通过静态方法创建，确保 timestamp 自动赋值
     */
    private BaseResponse() {
        // 初始化响应时间（UTC+8时区，统一时间格式）
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        this.timestamp = sdf.format(new Date());
    }

    /**
     * 私有构造：支持自定义核心字段
     */
    private BaseResponse(Boolean success, String code, String message, T data) {
        this(); // 调用无参构造，初始化timestamp
        this.success = success;
        this.code = code;
        this.message = message;
        this.data = data;
    }


    // ==================== getter/setter 方法（必须提供，用于序列化JSON返回给前端）====================
    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
}